package main

import (
	"log"
	"os"
	"os/signal"
	"strconv"
	"syscall"

	tinyiotserver "gitee.com/mqyqingkong/tiny-iot-server"
)

type CustomMsgHandlerSelector struct {
}

// DefineProcessorInTaskChan 为每个processor定义一个输入chan，返回值为输入chan的id
func (s *CustomMsgHandlerSelector) DefineProcessorInTaskChan() (processorInTaskChanIndex []int) {
	return []int{0, 1, 1, 1, 1}
}

// SelectInTaskChanIndex 将task分配给某个chan。
func (s *CustomMsgHandlerSelector) SelectInTaskChanIndex(topic string, payload []byte) (inTaskChanIndex int) {
	if topic == "door" {
		return 0
	}
	return 1
}

func main() {
	msgHandlerOption := tinyiotserver.WithMsgHandlerSelector(&CustomMsgHandlerSelector{})
	defaultQueueSizeOption := tinyiotserver.WithDefaultQueueSize(5120)
	sslOption := tinyiotserver.WithTLS("ssl/cert/server.key", "ssl/cert/server.crt")

	//创建server
	server := tinyiotserver.NewServer(":7070", msgHandlerOption, defaultQueueSizeOption, sslOption)
	// server := tinyiotserver.NewServer("example.sock", tinyiotserver.WithNetwork("unix"))

	//创建“温度-空调”处理逻辑
	turnOnTheAirConditionerMsgHandler := &TurnOnTheAirConditionerMsgHandler{}
	//注册处理逻辑
	//Temperature是主题（topic）名，每个topic会对应一个消息队列，框架会根据msg中的topic来路由到合适的handler
	server.RegisterHandler("Temperature", turnOnTheAirConditionerMsgHandler)

	//注册“开门-关门”处理逻辑
	doorMsgHandler := &DoorMsgHandler{}
	server.RegisterHandler("door", doorMsgHandler)

	//启动服务
	go server.Start()

	//
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	server.Close()

}

// TurnOnTheAirConditionerMsgHandler 处理温度事件，开空调。
// 处理逻辑：如果温度>28度，开启空调制冷（制冷温度为26度）
type TurnOnTheAirConditionerMsgHandler struct {
	tinyiotserver.MsgHandlerAdapter
}

// OnReceive 处理温度事件。
// requestMsg 为温度传感器发送来的消息，内容示例："35C"；
// newMsg 为生成的后续指令，供空调获取
func (h *TurnOnTheAirConditionerMsgHandler) OnReceive(requestMsg *tinyiotserver.Message) (newMsg *tinyiotserver.Message) {
	tag := "TurnOnTheAirConditionerMsgHandler"
	tmp := string(requestMsg.Body.Payload)
	tmp = tmp[0 : len(tmp)-1]
	tmpInt, err := strconv.Atoi(tmp)
	if err != nil {
		return tinyiotserver.FailMsg(string(requestMsg.Body.Topic), "Temperature content is not a number")
	}
	//温度>28度
	if tmpInt > 28 {
		newMsg = requestMsg.Copy()
		//生成空调消息（指令）
		newMsg.SetTopic("AirConditioner")
		newMsg.SetPayload([]byte("26C"))
		log.Printf("[%s] generate TurnOnAirConditioner msg:\n%s\n", tag, newMsg)
	}
	return
}

// DoorMsgHandler 处理开门--关门事件
type DoorMsgHandler struct {
	tinyiotserver.MsgHandlerAdapter
}

func (h *DoorMsgHandler) OnReceive(requestMsg *tinyiotserver.Message) (newMsg *tinyiotserver.Message) {
	tag := "DoorMsgHandler"
	log.Printf("[%s] received msg:\n%s\n", tag, requestMsg)
	payload := string(requestMsg.Body.Payload)

	if payload == "open" {
		log.Printf("[%s] door opened\n", tag)
	} else if payload == "close" {
		log.Printf("[%s] door closed\n", tag)
	}
	return requestMsg
}
